package com.haifeng.sbtx.auth.config;

import com.haifeng.sbtx.auth.exception.CustomWebResponseExceptionTranslator;
import com.haifeng.sbtx.auth.service.impl.CustomRedisAuthorizationCodeServices;
import lombok.AllArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
import org.springframework.security.oauth2.provider.token.TokenStore;

import javax.sql.DataSource;

/**
 * <p>
 *  认证服务器配置中心
 * </p>
 *
 * @author: Haifeng
 * @date: 2019-12-15
 */
@AllArgsConstructor
@Configuration
@EnableAuthorizationServer
public class CustomAuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

    private final DataSource dataSource;
    private final TokenStore tokenStore;
    private final CustomRedisAuthorizationCodeServices customRedisAuthorizationCodeServices;
    private final AuthenticationManager authenticationManagerBean;
    private final CustomWebResponseExceptionTranslator customWebResponseExceptionTranslator;

    @Bean
    public TokenEnhancer tokenEnhancer(){
        return new CustomTokenEnhancer();
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.reuseRefreshTokens(false)
                 .exceptionTranslator(customWebResponseExceptionTranslator)
                 .tokenStore(tokenStore)
                 .approvalStoreDisabled()
                 .tokenEnhancer(tokenEnhancer())
                 .authorizationCodeServices(customRedisAuthorizationCodeServices)
                 .authenticationManager(authenticationManagerBean)
                 .allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST);
        DefaultTokenServices tokenService = new DefaultTokenServices();
        tokenService.setTokenStore(tokenStore);
        tokenService.setSupportRefreshToken(true);
        tokenService.setTokenEnhancer(tokenEnhancer());
        tokenService.setReuseRefreshToken(false);
        endpoints.tokenServices(tokenService);

    }

    /**
     * 配置客户端信息
     * @param clients
     * @throws Exception
     */
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.jdbc(dataSource);
    }

    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) {
        security.tokenKeyAccess("permitAll()")
                .checkTokenAccess("permitAll()")
                .allowFormAuthenticationForClients();
    }
}
